package org.aceor.mddal.atom;

import org.aceor.mddal.atom.factory.DsFactory;
import org.aceor.mddal.atom.lifecycle.DsLifeCycle;
import org.aceor.mddal.atom.util.DsUtil;
import org.apache.commons.dbcp.BasicDataSource;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

/**
 * Created by lxue on 16/3/29.
 */
public class DBCPDatasourceWrapper implements DataSource, DsLifeCycle {

    private DataSource dataSource;

    private volatile boolean inited = false;

    private final String dbKey;

    public DBCPDatasourceWrapper(String dbKey) {
        this.dbKey = dbKey;
    }

    @Override
    public void init() throws Exception {
        if (inited) {
            throw new RuntimeException("已经初始化");
        }
        //TODO: 如何拿到config路径
        BasicDataSource dbcpDatasource = DsFactory.buildDbcpDatasource(null);
        if (DsUtil.checkDbcpDsNecessaryParams(dbcpDatasource)) {
            this.dataSource = dbcpDatasource;
            this.inited = true;
        } else {
            throw new RuntimeException("创建的dbcp数据源缺乏必要参数");
        }
    }

    @Override
    public void flush() throws Exception {
        //TODO: clone
    }

    @Override
    public void destroy() throws Exception {
        if (null != dataSource) {
            dataSource.getConnection().close();
        }
    }

    public DataSource getDataSource() {
        return dataSource;
    }

    @Override
    public Connection getConnection() throws SQLException {
        return new AtomConnectionWrapper(dataSource.getConnection(), this);
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return new AtomConnectionWrapper(dataSource.getConnection(username, password), this);
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return dataSource.getLogWriter();
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
        dataSource.setLogWriter(out);
    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
        dataSource.setLoginTimeout(seconds);
    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return dataSource.getLoginTimeout();
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return dataSource.getParentLogger();
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return this.getClass().isAssignableFrom(iface);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T> T unwrap(Class<T> iface) throws SQLException {
        try {
            return (T) this;
        } catch (Exception e) {
            throw new SQLException(e);
        }
    }
}
